import java.util.concurrent.PriorityBlockingQueue;

public class MyTimer {
    static class Task implements Comparable<Task>{
        // command : 这个任务是什么
        private Runnable command;
        // time : 这个任务啥时候到时间 (单位ms)
        private long time;

        public Task(Runnable command, long time) {
            this.command = command;
            this.time =System.currentTimeMillis()+time;
        }

        public void run(){
            command.run();
        }

        @Override
        public int compareTo(Task o) {
            return (int) (this.time - o.time);
        }
    }

    static class Timer{
        // 使用带优先级版本的阻塞队列来组织这些任务
        private PriorityBlockingQueue<Task> queue = new PriorityBlockingQueue<>();

        private Object locker = new Object();

        public void schedule(Runnable command,long delay){
            Task task = new Task(command,delay);
            queue.put(task);

            // 每次插入新的任务都要唤醒线程 让扫描现场能够重新计算wait时间,保证新任务不会操作(sleep做不到)
            synchronized (locker){
                locker.notify();
            }
        }

        public Timer(){
            // 创建一个扫描线程 ( 判断任务是不是已经到时间能执行了)
            Thread t = new Thread(){
                @Override
                public void run() {
                    while (true){
                        // 取出队列的首元素 判定时间是不是到了
                        try {
                            Task task = queue.take();
                            long curTime = System.currentTimeMillis();
                            if (task.time > curTime){
                                // 没到时间,暂时不执行
                                queue.put(task);
                                // 根据时间差 进行等待
                                synchronized(locker){
                                    locker.wait(task.time - curTime);
                                }
                            }else {
                                task.run();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            break;
                        }
                    }
                }
            };
            t.start();
        }
    }

    public static void main(String[] args) {
        System.out.println("程序启动");
        Timer timer = new Timer();
        timer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello");
            }
        }, 3000);
    }
}
